home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 020 / arcsourc.arc / ARCADD.MAC < prev    next >
Encoding:
Text File  |  1985-11-11  |  9.0 KB  |  209 lines

  1. /*  ARC - Archive utility - ARCADD
  2.  
  3. $define(tag,$$segment(@1,$$index(@1,=)+1))#
  4. $define(version,Version $tag(
  5. TED_VERSION DB =3.19), created on $tag(
  6. TED_DATE DB =11/11/85) at $tag(
  7. TED_TIME DB =17:19:20))#
  8. $undefine(tag)#
  9.     $version
  10.  
  11. (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  12.  
  13.     By:  Thom Henderson
  14.  
  15.     Description:
  16.          This file contains the routines used to add files to an archive.
  17.  
  18.     Language:
  19.          Computer Innovations Optimizing C86
  20. */
  21. #include <stdio.h>
  22. #include "arc.h"
  23.  
  24. addarc(num,arg,move,update,fresh)      /* add files to archive */
  25. int num;                               /* number of arguments */
  26. char *arg[];                           /* pointers to arguments */
  27. int move;                              /* true if moving file */
  28. int update;                            /* true if updating */
  29. int fresh;                             /* true if freshening */
  30. {
  31.     char *dir, *d, *filedir();         /* directory junk */
  32.     char buf[$strlen];                 /* pathname buffer */
  33.     char **path = NULL;                /* pointer to pointers to paths */
  34.     char **name = NULL;                /* pointer to pointers to names */
  35.     int nfiles = 0;                    /* number of files in lists */
  36.     char *i, *strrchr();               /* string indexing junk */
  37.     char *alloc(), *realloc();         /* memory allocators */
  38.     int m, n;                          /* indices */
  39.     struct heads hdr;                  /* file header data storage */
  40.  
  41.     if(num<1)                          /* if no files named */
  42.     {    num = 1;                      /* then fake one */
  43.          arg[0] = "*.*";               /* add everything */
  44.     }
  45.  
  46.     for(n=0; n<num; n++)               /* for each template supplied */
  47.     {    if(d=dir=filedir(arg[n],0))   /* get list of files */
  48.          {    strcpy(buf,arg[n]);
  49.               if(!(i=strrchr(buf,'\\')))
  50.                    if(!(i=strrchr(buf,'/')))
  51.                         if(!(i=strrchr(buf,':')))
  52.                              i = buf-1;
  53.               i++;                     /* pointer to where name goes */
  54.  
  55.               while(*d)                /* add all matching files */
  56.               {    nfiles++;
  57.                    path = (char **)realloc(path,nfiles*sizeof(char **));
  58.                    name = (char **)realloc(name,nfiles*sizeof(char **));
  59.                    strcpy(i,d);
  60.                    path[nfiles-1] = alloc(strlen(buf)+1);
  61.                    strcpy(path[nfiles-1],buf);
  62.                    name[nfiles-1] = d;
  63.                    while(*d++);        /* skip to next filename */
  64.               }
  65.          }
  66.  
  67.          else if(warn)
  68.               printf("No files match: %s\n",arg[n]);
  69.     }
  70.  
  71.     for(n=0; n<nfiles-1; n++)          /* sort the list of names */
  72.     {    for(m=n+1; m<nfiles; m++)
  73.          {    if(strcmp(name[n],name[m])>0)
  74.               {    d = path[n];
  75.                    path[n] = path[m];
  76.                    path[m] = d;
  77.                    d = name[n];
  78.                    name[n] = name[m];
  79.                    name[m] = d;
  80.               }
  81.          }
  82.     }
  83.  
  84.     for(n=0; n<nfiles-1; )             /* consolidate the list of names */
  85.     {    if(!strcmp(path[n],path[n+1]) /* if duplicate names */
  86.          || !strcmp(path[n],arcname)   /* or this archive */
  87.          || !strcmp(path[n],newname)   /* or the new version */
  88.          || !strcmp(path[n],bakname))  /* or its backup */
  89.          {    for(m=n; m<nfiles-1; m++)/* then forget a file */
  90.               {    path[m] = path[m+1];
  91.                    name[m] = name[m+1];
  92.               }
  93.               nfiles--;
  94.          }
  95.          else n++;                     /* else test the next one */
  96.     }
  97.  
  98.     if(!nfiles)                        /* make sure we got some */
  99.          abort("I have no work to do!");
  100.  
  101.     for(n=0; n<nfiles-1; n++)          /* watch out for duplicate names */
  102.          if(!strcmp(name[n],name[n+1]))
  103.               abort("Duplicate filenames:\n  %s\n  %s",path[n],path[n+1]);
  104.  
  105.     openarc(1);                        /* open archive for changes */
  106.  
  107.     for(n=0; n<nfiles; n++)            /* add each file in the list */
  108.          addfile(path[n],name[n],move,update,fresh);
  109.  
  110.     /* now we must copy over all files that follow our additions */
  111.  
  112.     while(readhdr(&hdr,arc))           /* while more entries to copy */
  113.     {    writehdr(&hdr,new);
  114.          filecopy(arc,new,hdr.size);
  115.     }
  116.     hdrver = 0;                        /* archive EOF type */
  117.     writehdr(&hdr,new);                /* write out our end marker */
  118.     closearc(1);                       /* close archive after changes */
  119. }
  120.  
  121. static addfile(path,name,move,update,fresh) /* add named file to archive */
  122. char *path;                            /* path name of file to add */
  123. char *name;                            /* name of file to add */
  124. int move;                              /* true if moving */
  125. int update;                            /* true if updating */
  126. int fresh;                             /* true if freshening */
  127. {
  128.     struct heads nhdr;                 /* data regarding the new file */
  129.     struct heads ohdr;                 /* data regarding an old file */
  130.     FILE *f, *fopen();                 /* file to add, opener */
  131.     long starts, ftell();              /* file locations */
  132.     int c;                             /* one char of file */
  133.     int upd = 0;                       /* true if replacing an entry */
  134.  
  135.     if(!(f=fopen(path,"rb")))
  136.     {    if(warn)
  137.               printf("Cannot read file: %s\n",path);
  138.          return;
  139.     }
  140.  
  141.     strcpy(nhdr.name,name);            /* save name */
  142.     nhdr.size = 0;                     /* clear out size storage */
  143.     nhdr.crc = 0;                      /* clear out CRC check storage */
  144.     getstamp(f,&nhdr.date,&nhdr.time);
  145.  
  146.     /* position archive to spot for new file */
  147.  
  148.     if(arc)                            /* if adding to existing archive */
  149.     {    starts = ftell(arc);          /* where are we? */
  150.          while(readhdr(&ohdr,arc))     /* while more files to check */
  151.          {    if(!strcmp(ohdr.name,nhdr.name))
  152.               {    upd = 1;            /* replace existing entry */
  153.                    if(update || fresh) /* if updating or freshening */
  154.                    {    if(nhdr.date<ohdr.date
  155.                         || (nhdr.date==ohdr.date && nhdr.time<=ohdr.time))
  156.                         {    fseek(arc,starts,0);
  157.                              fclose(f);
  158.                              return;   /* skip if not newer */
  159.                         }
  160.                    }
  161.               }
  162.  
  163.               if(strcmp(ohdr.name,nhdr.name)>=0)
  164.                    break;              /* found our spot */
  165.  
  166.               writehdr(&ohdr,new);     /* entry preceeds update; keep it */
  167.               filecopy(arc,new,ohdr.size);
  168.               starts = ftell(arc);     /* now where are we? */
  169.          }
  170.  
  171.          if(upd)                       /* if an update */
  172.          {    if(note)
  173.                    printf("Updating file: %-12s  ",name);
  174.               fseek(arc,ohdr.size,1);
  175.          }
  176.          else if(fresh)                /* else if freshening */
  177.          {    fseek(arc,starts,0);     /* then do not add files */
  178.               fclose(f);
  179.               return;
  180.          }
  181.          else                          /* else adding a new file */
  182.          {    if(note)
  183.                    printf("Adding file:   %-12s  ",name);
  184.               fseek(arc,starts,0);     /* reset for next time */
  185.          }
  186.     }
  187.  
  188.     else                               /* no existing archive */
  189.     {    if(fresh)                     /* cannot freshen nothing */
  190.          {    fclose(f);
  191.               return;
  192.          }
  193.          else if(note)                 /* else adding a file */
  194.               printf("Adding file:   %-12s  ",name);
  195.     }
  196.  
  197.     starts = ftell(new);               /* note where header goes */
  198.     hdrver = $arcver;                  /* anything but end marker */
  199.     writehdr(&nhdr,new);               /* write out header skeleton */
  200.     pack(f,new,&nhdr);                 /* pack file into archive */
  201.     fseek(new,starts,0);               /* move back to header skeleton */
  202.     writehdr(&nhdr,new);               /* write out real header */
  203.     fseek(new,nhdr.size,1);            /* skip over data to next header */
  204.     fclose(f);                         /* all done with the file */
  205.     if(move)                           /* delete source when moving */
  206.          if(unlink(path) && warn)
  207.               printf("Cannot unsave %s\n",path);
  208. }
  209.